
package jp.ize.iwp.utils;

// {{{ prepare
#if flash9
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Loader;
import flash.system.LoaderContext;
import flash.geom.Point;
import flash.Error;
#elseif flash
import flash.MovieClip;
import jp.ize.iwp.avm1.display.Loader;
import jp.ize.iwp.avm1.geom.Point;
import jp.ize.iwp.avm1.Error;
typedef DisplayObjectContainer = MovieClip;
typedef Sprite = MovieClip;
#end
// }}}

/**
* ResourceManager クラスです。<br />
* デザイン・リソースを扱うためのクラスです。
*/
class ResourceManager
{
	// {{{ properties
	/** リソースを割り当てる基になるコンテナの一覧です。 */
	public var containers:Hash<DisplayObjectContainer>;
	/** リソースの一覧です。 */
	public var resources:Hash<Hash<Sprite>>;

	// }}}
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		containers = new Hash();
		resources = new Hash();
	}

	// }}}
	// {{{ public function setContainerResource( id:String, target:DisplayObjectContainer ) : Void
	/**
	* コンテナを設定します。
	* 任意のIDを設定します。target には、コンテナを指定します。
	*/
	public function setContainerResource( id:String, target:DisplayObjectContainer ) : Void
	{
		containers.set(id,target);
	}

	// }}}
	// {{{ public function addResource( id:String, name:String, loader:Loader, classname:String, ?pos:Point ) : Void
	/**
	* リソースを追加します。
	* @param id: コンテナのIDを指定します。
	* @param name: リソースに任意の名前を割り当てます。
	* @param loader: Flash Player 8 以下の互換のための引数です。Loader を指定します。
	* @param classname: リソースのクラス名を指定します。
	* @param pos: 表示位置を指定する場合は、指定します。
	*/
	public function addResource( id:String, name:String, loader:Loader, classname:String, ?pos:Point ) : Void
	{
		try {
			#if flash9
			var obj:Sprite = ClassUtil.getInstance(classname);
			if ( obj==null ) return;
			obj.x = pos.x;
			obj.y = pos.y;
			#elseif flash
			var obj:Sprite = ClassUtil.getInstance(classname,loader);
			if ( obj==null ) return;
			obj._x = pos.x;
			obj._y = pos.y;
			#end
			var target = containers.get(id);
			var resource = new Hash<Sprite>();
			if ( resources.exists(id) ) {
				resource = resources.get(id);
			}
			if ( resource.exists(name) ) {
				var o = resource.get(name);
				#if flash9
				target.removeChild( o );
				#elseif flash
				o.removeMovieClip();
				#end
				resource.remove(name);
			}
			resource.set( name, obj );
			resources.set(id, resource);
			#if flash9
			target.addChild( obj );
			#elseif flash
			#end
		} catch ( e:Dynamic ) {
			trace(e);
		}
	}

	// }}}
	// {{{ public function removeResource( id:String, name:String, ?pos:Point ) : Void
	/**
	* リソースを削除します。
	* 指定したコンテナID の中にある指定してリソース名のリソースを削除します。
	*/
	public function removeResource( id:String, name:String, ?pos:Point ) : Void
	{
		var target = containers.get(id);
		var resource = null;
		if ( resources.exists(id) ) {
			resource = resources.get(id);
			if ( resource==null ) return;
			if ( resource.exists(name) ) {
				var obj = resource.get(name);
				if ( obj==null ) return;
				#if flash9
				target.removeChild( obj );
				#elseif flash
				obj.removeMovieClip();
				#end
			} else {
				throw new Error("name not found in resource");
			}
		} else {
			throw new Error("id not found in resources");
		}
	}

	// }}}
	// {{{ public function getResource( id:String, name:String ) : Dynamic
	/**
	* リソースを取得します。
	* 指定したコンテナID の中にある指定してリソース名のリソースを取得します。
	*/
	public function getResource( id:String, name:String ) : Dynamic
	{
		var target = containers.get(id);
		var resource = null;
		if ( resources.exists(id) ) {
			resource = resources.get(id);
			if ( resource==null ) return null;
			if ( resource.exists(name) ) {
				var obj = resource.get(name);
				return obj;
			} else {
				throw new Error("name not found in resource");
			}
		} else {
			throw new Error("id not found in resources");
		}
		return null;
	}

	// }}}
}
